<?php


namespace EchoPHP\Database\TuxedoDriver;


use Closure;
use EchoPHP\Database\Exceptions\QueryException;
use EchoPHP\Database\Exceptions\TuxedoTransactionException;
use EchoPHP\Facades\Log;
use EchoPHP\Support\Str;
use Exception;

class TransactionHandler extends Handler {

    /**
     * 事务处理逻辑
     * @param $sqls
     * @return mixed
     */
    protected function run($sqls) {
        $start = microtime(true);

        try {
            $result = $this->callTuxedo();
        } catch (Exception $e) {
            /* @var TuxedoStatement $tuxedoStatement */
            $querys = [];
            foreach ($sqls as $sql) {
                $querys[] = '[(' . $sql['serverdbtype'] . ':' . $sql['dbid'] . '):' . Str::replaceArray('?', $sql['bindings'], $sql['query']) . ']';
            }
            $sqlContext = [
                'sqls' => $querys,
                'message' => $e->getMessage(),
            ];
            if (method_exists($e, 'getServerName')) {
                $sqlContext['servername'] = $e->getServerName();
                $sqlContext['sendbuffer'] = $e->getSendBuffer();
                $sqlContext['receivebuffer'] = $e->getReceiveBuffer();
            }
            Log::error('SQL执行出现错误', $sqlContext, 'errorsql');
            throw new TuxedoTransactionException($querys, $e);
        }
        $costTime = round((microtime(true) - $start) * 1000, 2);
        $this->logQuery($sqls, $costTime);

        return $result;
    }

    protected function logQuery($sqls, $costTime) {
        $slowLogTime = config('app.debug.slowsql', 0);
        if ($costTime > $slowLogTime && $slowLogTime > 0) {
            $sqlContext = [
                'costtime' => $costTime,
            ];
            foreach ($sqls as $sql) {
                $sqlContext['sqls'][] = [
                    'db' => $sql['serverdbtype'] . ':' . $sql['dbid'],
                    'query' => $sql['query'],
                    'bindings' => $sql['bindings'],
                ];
            }
            Log::warning('SQL执行耗时过长', $sqlContext, 'slowsql');
        }
        $traceSql = config('app.debug.tracesql', false);
        if ($traceSql) {
            if (!isset($sqlContext)) {
                $sqlContext = [
                    'costtime' => $costTime,
                ];
                foreach ($sqls as $sql) {
                    $sqlContext['sqls'][] = [
                        'db' => $sql['serverdbtype'] . ':' . $sql['dbid'],
                        'query' => $sql['query'],
                        'bindings' => $sql['bindings'],
                    ];
                }
            }
            Log::debug('trace sql info', $sqlContext, 'tracesql');
        }
    }
}